package com.hicorp.segment.service.impl;

import com.hicorp.segment.mapper.MenuMapper;
import com.hicorp.segment.mapper.RoleMenuRelationMapper;
import com.hicorp.segment.mapper.UserMapper;
import com.hicorp.segment.mapper.UserRoleRelationMapper;
import com.hicorp.segment.pojo.po.Menu;
import com.hicorp.segment.pojo.po.RoleMenuRelation;
import com.hicorp.segment.pojo.po.User;
import com.hicorp.segment.pojo.po.UserRoleRelation;
import com.hicorp.segment.service.AuthorityService;
import com.hicorp.segment.utils.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author:
 * @Date: Created in 4:24 2021/5/19
 * @Description:
 * @ChineseDescription:
 * @Modified_By:
 */
@Service("userService")
@Slf4j
public class AuthorityServiceImpl implements AuthorityService {
    @Resource
    private UserMapper userMapper;

    @Resource
    private MenuMapper menuMapper;

    @Resource
    private RoleMenuRelationMapper roleMenuRelationMapper;

    @Resource
    private UserRoleRelationMapper userRoleRelationMapper;

    @Override
    public User getUser(String username) {
        return userMapper.findByUserName(username);
    }

    /**
     * 用户注册
     *
     * @param user 前端传来的用户信息
     * @return 标准返还
     */
    @Override
    public ResultBean<Void> register(User user) {
        try {
            String str1 = "000" + (Integer.parseInt(userMapper.findLastUserNO()) + 1);
            String returnNO = str1.substring(str1.length() - 4);
            user.setUserNo(returnNO);
            userMapper.insert(user);
            return new ResultBean<>();
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "用户添加失败!");
        }
    }

    /**
     * 查询所有的菜单(返回树形结构)
     *
     * @return 返回树形结构
     */
    @Override
    public ResultBean<List<Menu>> selectAllMenuTree() {
        List<Menu> menuList = menuMapper.selectAll();
        try {
            List<Menu> menuTree =
                    menuList
                            .stream()
                            .filter(menu -> menu.getParentId() != null)
                            .filter(menu -> 1 == menu.getParentId())
                            .peek(menu -> menu.setChildren(getMenuChildren(menu, menuList)))
                            .collect(Collectors.toList());
            return new ResultBean<>(menuTree);
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "查询菜单错误,请联系管理员!");
        }
    }

    /**
     * 设置角色可访问的菜单
     *
     * @param roleMenuRelations 角色菜单关系
     * @return 是否成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultBean<Void> setRoleMenuRelation(List<RoleMenuRelation> roleMenuRelations) {
        try {
            Long roleId = roleMenuRelations.get(0).getRoleId();
            List<Long> menuIds = roleMenuRelationMapper.selectMenuIdByRoleId(roleId);
            if (!menuIds.isEmpty()) {
                roleMenuRelationMapper.deleteByRoleId(roleId);
            }
            roleMenuRelationMapper.insertList(roleMenuRelations);
            return new ResultBean<>();
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "设置权限失败!");
        }
    }

    /**
     * 设置用户角色
     *
     * @param userRoleRelations 用户角色关系
     * @return 是否成功
     */
    @Override
    public ResultBean<Void> setUserRoleRelation(List<UserRoleRelation> userRoleRelations) {
        try {
            Long userId = userRoleRelations.get(0).getUserId();
            List<Long> roleIds = userRoleRelationMapper.selectRoleIdByUserId(userId);
            if (!roleIds.isEmpty()) {
                userRoleRelationMapper.deleteByUserId(userId);
            }
            userRoleRelationMapper.insertList(userRoleRelations);
            return new ResultBean<>();
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "设置用户角色失败!");
        }
    }

    /**
     * 根据角色id查询其可访问的菜单的id
     *
     * @param roleId 角色id
     * @return 可访问的菜单的id
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public ResultBean<List<Long>> selectMenuIdByRoleId(Long roleId) {
        try {
            List<Long> menuIdList = roleMenuRelationMapper.selectMenuIdByRoleId(roleId);
            return new ResultBean<>(menuIdList);
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "查询角色可访问的菜单失败!");
        }
    }

    /**
     * 根据用户id查询角色id
     *
     * @param userId 用户id
     * @return 用户角色id
     */
    @Override
    public ResultBean<List<Long>> selectRoleIdByUserId(Long userId) {
        try {
            List<Long> roleIdList = userRoleRelationMapper.selectRoleIdByUserId(userId);
            return new ResultBean<>(roleIdList);
        } catch (Exception e) {
            log.error(e.getMessage());
            return new ResultBean<>(400, "查询用户角色失败!");
        }
    }

    // 生成树形结构的菜单.
    private List<Menu> getMenuChildren(Menu rootMenu, List<Menu> allMenuList) {
        return allMenuList
                .stream()
                .filter((menu) -> Objects.equals(rootMenu.getId(), menu.getParentId()))
                .collect(Collectors.toList());
    }
}
